home *** CD-ROM | disk | FTP | other *** search
/ Technotools / Technotools (Chestnut CD-ROM)(1993).ISO / lang_asm / hercbios / hercbios.asm < prev    next >
Encoding:
Assembly Source File  |  1979-12-31  |  14.4 KB  |  407 lines

  1. ;*******************************************************
  2. ;*
  3. ;*     Main program file for HERCBIOS
  4. ;*
  5. ;*             Dave Tutelman - 8/86
  6. ;*
  7. ;*------------------------------------------------------
  8. ;*
  9. ;*     INT10 -- acts as pre-handler for video interrupts
  10. ;*     (BIOS calls) for Hercules & SuperComputer
  11. ;*     monochrome graphics board.  Calls real BIOS
  12. ;*     if not a Hercules special. Handled here are:
  13. ;*
  14. ;*     Fn 0    Set mode (only 6 & 8)
  15. ;*     and all functions, when in mode 6 or 8.
  16. ;*     Actually, we've only implemented:
  17. ;*     Fn 2    Set cursor position
  18. ;*     Fn 3    Read cursor position
  19. ;*     Fn 5    New display page
  20. ;*     Fn 9    Write character with attribute
  21. ;*     Fn 10   Write character
  22. ;*     Fn 12   Write pixel
  23. ;*     Fn 13   Read pixel
  24. ;*     Fn 14   Teletypewriter-style character write
  25. ;*     Fn 15   Get video status
  26. ;*
  27. ;*     The only allowable modes for these boards are:
  28. ;*     6       IBM graphics (we handle it, but poor aspect ratio).
  29. ;*     7       Monochrome (with 2 pages)
  30. ;*     8       Hercules graphics mode.
  31. ;*
  32. ;**********************************************************
  33. ;
  34. INCLUDE        hercbios.h
  35.  
  36. extrn  writechar:near,tty:near,scroll_up:near,scroll_down:near
  37. extrn  scr_start:word,scr_length:word,num_rows:byte
  38. extrn  wr_pixel:near
  39. extrn  end_herc:near
  40. public exit_herc_bios,int10,vid_vector
  41. public set_mode,set_curs,read_curs,new_page,status
  42. ;-----------------------------------------
  43. page
  44. ;************************************************************
  45. ;*
  46. ;*     Install the Hercules video handler
  47. ;*
  48. ;************************************************************
  49. cseg   segment public
  50.        assume  cs:cseg,ds:cseg
  51.  
  52.        ORG     100h
  53. ;
  54. START:
  55. ;
  56.        push    ax
  57.        push    es
  58.        push    ds
  59. ;
  60.        xor     ax,ax           ; zero the acc
  61.        mov     es,ax           ; ES points to zero (interrupt vector)
  62.     ; Get ROM BIOS video entry point, and save in "rom_bios"
  63.        mov     ax,es:[4*VIDI]
  64.        mov     word ptr cs:rom_bios,ax
  65.        mov     ax,es:[4*VIDI+2]
  66.        mov     word ptr cs:rom_bios+2,ax
  67.     ; Now plant the HERCBIOS entry point in interrupt vector
  68.        mov     ax,offset int10 ; address of video handler to AX
  69.        mov     es:[4*VIDI],ax  ; and store it in interrupt vector 10H
  70.        mov     ax,cs           ; same for the segment of video handler
  71.        mov     es:[4*VIDI+2],ax        ; ...
  72. ;
  73. ;   Leave the message that we're installed
  74.        mov     ax,cs           ; DS:DX pointing to message
  75.        mov     ds,ax
  76.        mov     dx,offset install_msg
  77.        mov     ah,9            ; display-string function
  78.        int     21h
  79.  
  80.        pop     ds
  81.        pop     es
  82.        pop     ax
  83. ;
  84.        mov     dx,offset end_herc      ; set dx to end of this program
  85.        int     27H             ; terminate, but stay resident
  86. ;
  87. install_msg    db      "BIOS for Hercules-compatible Graphics - "
  88.        db              "(DMT Aug 1986)",10,13,'$'
  89. page
  90. ;************************************************************
  91. ;*
  92. ;*     Beginning of video interrupt handler
  93. ;*
  94. ;************************************************************
  95. ;
  96. ;
  97. int10  proc    far
  98. ;
  99.        sti                     ; allow further interrupts
  100.        push    ds              ; save DS
  101.        push    ax              ; save AX
  102.        mov     ax,bios_data    ; bios data segment --> AX
  103.        mov     ds,ax           ; now put bios data segment in DS
  104.        assume  ds:bios_data    ; and tell assembler about it
  105. ;                      ; check current mode
  106.        mov     ah,video_mode   ; get current mode
  107.        cmp     ah,herc_mode    ; test for a graphics mode
  108.        je      herc_bios
  109.        cmp     ah,ibm_mode
  110.        je      herc_bios
  111. ;                      ; setmode to a graphics mode?
  112.        pop     ax              ; restore AX
  113.        push    ax              ; ...but leave it on stack
  114.        cmp     ax,0006         ; Fn = set to IBM hi-res mode?
  115.        je      herc_bios
  116.        cmp     ax,0008         ; Fn = set to Herc graphics mode?
  117.        je      herc_bios
  118. ;
  119. norm_bios:             ; if we get here, just go to real BIOS
  120.        pop     ax              ; restore stack to pre-interrupt state
  121.        pop     ds
  122.        db      0EAh    ; opcode for FAR JUMP to rom_bios
  123. rom_bios       dd      ?       ; normal video bios address (in ROM)
  124. ;
  125. herc_bios:             ; jump table for special Hercules BIOS
  126. ;
  127.        pop     ax      ; restore ax
  128.        push    bx      ; save regs
  129.        push    cx
  130.        push    dx
  131.        push    si
  132.        push    di
  133.        push    es
  134. ;
  135.        push    ax
  136.        mov     al,ah           ; function # to AX
  137.        xor     ah,ah
  138.        shl     ax,1            ; *2 for word vector
  139.        mov     si,ax           ; put in SI to index into vector
  140.        pop     ax              ; restore old AX
  141.        cmp     si,offset vid_vec_end-offset vid_vector
  142.                                ; function number within range?
  143.        jge     exit_herc_bios  ; function number out of range
  144.        add     si,offset vid_vector
  145.        jmp     word ptr cs:[si]
  146.                                ; jump to routine via vector
  147. ;
  148.  
  149. vid_vector:            ; jump vector for hercules video routines
  150.        dw      offset set_mode                 ; 0 = set mode
  151.        dw      offset exit_herc_bios           ; 1 = cursor type (NA)
  152.        dw      offset set_curs                 ; 2 = set cursor position
  153.        dw      offset read_curs                ; 3 = read cursor position
  154.        dw      offset exit_herc_bios           ; 4 = light pen (NA)
  155.        dw      offset new_page                 ; 5 = choose active page
  156.        dw      offset scroll_up                ; 6 = scroll up
  157.        dw      offset scroll_down              ; 7 = scroll down
  158.        dw      offset exit_herc_bios           ; 8 = read character (NA)
  159.        dw      offset writechar                ; 9 = write char & attribute
  160.        dw      offset writechar                ;10 = write character
  161.        dw      offset exit_herc_bios           ;11 = set color palette (NA)
  162.        dw      offset wr_pixel                 ;12 = write pixel
  163.        dw      offset wr_pixel                 ;13 = read pixel
  164.        dw      offset tty                      ;14 = teletype write
  165.        dw      offset status                   ;15 = return video state
  166. vid_vec_end:
  167. ;
  168. exit_herc_bios:
  169.        pop     es      ; restore regs
  170.        pop     di
  171.        pop     si
  172.        pop     dx
  173.        pop     cx
  174.        pop     bx
  175.        pop     ds
  176.        iret            ; and return
  177. page
  178. ;********************************************************************
  179. ;*
  180. ;*     FUNCTION 0 - SET VIDEO MODE
  181. ;*
  182. ;*     Only gets here to set a hi-res graphics mode
  183. ;*             6=IBM
  184. ;*             8=Hercules
  185. ;*     [ AX destroyed ]
  186. ;*
  187. ;*******************************************************************
  188. ;
  189. set_mode:
  190. ;                      ; is it a graphics mode?
  191.        cmp     al,herc_mode    ; set to hercules mode?
  192.        je      g_mode
  193.        cmp     al,ibm_mode     ; set to IBM mode?
  194.        je      g_mode
  195.                                ; Neither. Leave it to normal BIOS
  196.        pop     es              ; restore regs
  197.        pop     di
  198.        pop     si
  199.        pop     dx
  200.        pop     cx
  201.        pop     bx
  202.        pop     ds
  203.        jmp     vid_bios        ; and go to MPX-16 BIOS
  204. ;
  205. g_mode:        mov     video_mode,al   ; save video mode in BIOS data area
  206.        mov     active_page,ah  ; zero the active page in BIOS data
  207.        mov     n_cols,90       ; 90 character columns in graphics mode
  208. ;
  209. ;*  clear display area
  210.        mov     ax,pixbase      ; get starting address
  211.        mov     es,ax           ; page base to ES
  212.        mov     cx,8000H        ; word counter
  213.        mov     di,0            ; start at beginning of display
  214.        cld                     ; direction "up"
  215.        xor     ax,ax           ; zero AX
  216.        rep     stosw           ; write zero to both pages
  217. ;
  218. ;*  load the 6845 internal registers
  219. ;
  220. ;                      ; first set up the loop
  221.        push    ds              ; save DS
  222.        mov     ax,cs           ; get cseg into DS
  223.        mov     ds,ax
  224.        assume  ds:cseg
  225.        mov     dx,vid_port     ; 6845 index port address to DX
  226.        mov     si,offset vid_parm_table
  227.                                ; table pointer to SI
  228.        mov     cx,16           ; 16 parameters in table
  229.        xor     ax,ax           ; zero AX (AH will be index counter)
  230. ;                      ; now execute the loop
  231. init_6845_loop:
  232.        mov     al,ah           ; index counter to AL
  233.        out     dx,al           ; output index to 6845
  234.        inc     dx              ; point DX to data reg
  235.        mov     al,[si]         ; get table entry
  236.        out     dx,al           ; output to 6845 data reg
  237.        dec     dx              ; point DX back to index reg
  238.        inc     ah              ; bump index counter
  239.        inc     si              ; bump table pointer
  240.        loop    init_6845_loop
  241.        pop     ds              ; restore DS
  242.        assume  ds:bios_data    ; restore DS assumed
  243. ;
  244. ;*  now set the 6845 control register
  245.        mov     dx,vid_port+4   ; control port address
  246.        mov     al,0AH          ; graphics control byte
  247.        cmp     active_page,0   ; get current page
  248.        je      pg0_F0          ; skip if zero
  249.        or      al,80H          ; page 1 to control byte
  250. pg0_F0:        out     dx,al           ; and ship to 6845
  251.        mov     chip_ctrl,al    ; also save in bios data area
  252. ;
  253. ;*  save cursor position (0,0) in bios data area
  254.        xor     ax,ax           ; zero AX
  255.        mov     curs_pos,ax     ; write zero to pg.0 cursor postion
  256.        mov     curs_pos+2,ax   ; write zero to pg.1 cursor postion
  257. ;
  258. ;*  initialize scrolling parameters
  259. ;
  260.        cmp     video_mode,herc_mode
  261.        je      h_parm
  262.        mov     cs:scr_start,180        ; IBM parameters
  263.        mov     cs:scr_length,3690      ;
  264.        mov     cs:num_rows,42          ;
  265.        jmp     parm_done
  266. h_parm:        mov     cs:scr_start,270        ; Herc parameters
  267.        mov     cs:scr_length,3645      ;
  268.        mov     cs:num_rows,28          ;
  269. parm_done:
  270. ;
  271.        jmp     exit_herc_bios
  272. ;
  273. ;*  table of 6845 chip parameters
  274. ;
  275. vid_parm_table db      53,45,46,7,91,2,87,87,2,3,62H,3,0,0,0,0
  276. ;vid_parm_table        db      54,45,46,8,91,2,87,87,2,3,62H,3,0,0,0,0
  277.                                                ;DMT's monitor
  278. page
  279. ;********************************************************************
  280. ;*
  281. ;*     FUNCTION 2 - SET CURSOR POSITION
  282. ;*
  283. ;*     DX = new row (DH) and column (DL)
  284. ;*     BH = display page number
  285. ;*
  286. ;********************************************************************
  287. ;
  288. set_curs:
  289. ;
  290. ; *   save in BIOS data area
  291.        mov     bl,bh           ; page # to bl
  292.        xor     bh,bh           ; zero bh (page # = BX)
  293.        shl     bx,1            ; times 2 for word
  294.        mov     curs_pos[bx],dx ; store in data area
  295. ;
  296. ; *   if page # = active page, then we should actually move cursor
  297. ; *            However, cursor doesn't show in graphics mode, so we won't.
  298. ;
  299.        jmp     exit_herc_bios
  300. ;
  301. page
  302. ;********************************************************************
  303. ;*
  304. ;*     FUNCTION 3 - READ CURSOR POSITION
  305. ;*
  306. ;*     on entry
  307. ;*             BH = display page number
  308. ;*
  309. ;*     on exit
  310. ;*             CX = cursor type/size
  311. ;*             DX = current row (DH) and column (DL)
  312. ;*
  313. ;********************************************************************
  314. ;
  315. read_curs:
  316. ;                      ; uncover the return portion of the stack
  317.        pop     es
  318.        pop     di
  319.        pop     si
  320.        pop     dx
  321.        pop     cx
  322. ;                      ; now get the data and push onto stack
  323.        push    curs_mode       ; cursor type to CX position in stack
  324.        mov     bl,bh           ; page # to BX
  325.        xor     bh,bh
  326.        shl     bx,1            ; *2 for word offset
  327.        push    curs_pos[bx]    ; cursor position for specified page
  328.                                ;   to DX position in stack
  329. ;                      ; refill the stack for return
  330.        push    si
  331.        push    di
  332.        push    es
  333. ;
  334.        jmp     exit_herc_bios
  335. page
  336. ;********************************************************************
  337. ;*
  338. ;*     FUNCTION 5 - SELECT NEW DISPLAY PAGE
  339. ;*
  340. ;*     AL = new display page number
  341. ;*
  342. ;********************************************************************
  343. ;
  344. new_page:
  345.        cmp     al,2            ; page < 2?
  346.        jl      f5_1            ; yup
  347.        jmp     exit_herc_bios  ; nope. can't do it.
  348. ;
  349. f5_1:  mov     active_page,al  ; put away active page in bios data
  350. ;  * put starting address in 6845 register 12
  351.        mov     ah,al           ; save page number in AH
  352.        mov     dx,vid_port     ; index pointer address
  353.        mov     al,12           ; save in register 12
  354.        out     dx,al           ; and set index pointer to 12
  355.        mov     al,ah           ; restore page to AL
  356.        ror     al,1            ; page to high-order bit
  357.        shr     al,1            ; two bytes per word
  358.        inc     dx
  359.        out     dx,al           ; ...and output it to register
  360. ;  * put control byte in 6845 port
  361.        mov     al,ah           ; get back page number
  362.        ror     al,1            ; page to high-order bit
  363.        or      al,0AH          ; create chip control byte
  364.        mov     chip_ctrl,al    ; save it in data area
  365.        mov     dx,vid_port+4   ; control port address
  366.        out     dx,al           ; send control byte to chip
  367. ;
  368.        jmp     exit_herc_bios
  369. page
  370. ;***********************************************************************
  371. ;*
  372. ;*     FUNCTION 15 - RETURN VIDEO STATUS
  373. ;*
  374. ;*     On exit:
  375. ;*             AL = current video mode
  376. ;*             AH = number of active display columns
  377. ;*             BH = current active page number
  378. ;*
  379. ;***********************************************************************
  380. ;
  381. status:
  382. ;                      ; first uncover the stack
  383.        pop     es
  384.        pop     di
  385.        pop     si
  386.        pop     dx
  387.        pop     cx
  388.        pop     bx
  389. ;                      ; now get the parameters needed
  390.        mov     al,video_mode
  391.        mov     ah,90           ; all our graphics modes have 90 cols
  392.        mov     bh,active_page
  393. ;                      ; and push back onto the stack for return
  394.        push    bx
  395.        push    cx
  396.        push    dx
  397.        push    si
  398.        push    di
  399.        push    es
  400. ;
  401.        jmp     exit_herc_bios
  402. ;
  403. int10  endp
  404. ;
  405. cseg   ends
  406.        end     START
  407.